package com.froggushka.api.onehourtranslation;

/*
Copyright (c) 2011 Froggushka

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.json.JSONException;
import org.json.JSONObject;

import com.froggushka.api.onehourtranslation.RequestOptions.ContentTypeEnum;

public class ResponceHelper
{

  public static final String STATUS_CODE = "status_code";
  public static final String STATUS_MESSAGE = "status_msg";
  public static final String ERRORS = "errors";
  public static final String ACCOUNT_ID = "account_id";
  public static final String ACCOUNT_USERNAME = "account_username";
  public static final String CREDIT_BALANCE = "credit_balance";

  public static final String ORIGINAL_CONTENT = "original_content";
  public static final String TRANSLATED_CONTENT = "translated_content";
  public static final String CONTENT_TYPE = "content_type";

  public static final String PROJECT_ID = "project_id";
  public static final String WORD_COUNT = "word_count";
  public static final String SOURCE = "source";
  public static final String TARGET = "target";
  public static final String CREDITS = "credits";
  public static final String ESTIMATE_FINISH = "estimate_finish";
  public static final String TRANSLATION_READY = "translation_ready";
  public static final String PROJECT_URL = "project_url";
  
  public static final String USER_REFERANCE = "user_reference";
  public static final String PROJECT_REFERANCE = "project_reference";
  public static final String CUSTOM = "custom";


  private final Log log = LogFactory.getLog(getClass());
  JSONObject m_oJSONResponce;

  public ResponceHelper(String json) throws OneHourTranslationException
  {
    try
    {
      m_oJSONResponce = new JSONObject(json);
    }
    catch (JSONException exp)
    {
      log.error(exp.getLocalizedMessage(), exp);
      throw new OneHourTranslationException(exp.getLocalizedMessage(), (Exception) exp);
    }
  }

  private int getInt(String p_strKey, int p_iDefaultValue)
  {
    int retVal = p_iDefaultValue;
    try
    {
      retVal = m_oJSONResponce.getInt(p_strKey);
    }
    catch (JSONException exp)
    {
      log.debug(exp.getLocalizedMessage(), exp);
    }
    return retVal;
  }

  private String getString(String p_strKey, String  p_strDefaultValue)
  {
    String retVal = p_strDefaultValue;
    try
    {
      retVal = m_oJSONResponce.getString(p_strKey);
    }
    catch (JSONException exp)
    {
      log.debug(exp.getLocalizedMessage(), exp);
    }
    return retVal;
  }
  
  private byte[] getByteArray(String p_strKey, byte[]  p_strDefaultValue)
  {
    byte[] retVal = p_strDefaultValue;
    try
    {
      String strEncodedContent = m_oJSONResponce.getString(p_strKey);
      retVal = Base64.decodeBase64(strEncodedContent);

    }
    catch (JSONException exp)
    {
      log.debug(exp.getLocalizedMessage(), exp);
    }
    return retVal;
  }
  
  private LanguageEnum getLanguage(String p_strKey)
  {
    String retVal = null;
    try
    {
      retVal = m_oJSONResponce.getString(p_strKey);
    }
    catch (JSONException exp)
    {
      log.debug(exp.getLocalizedMessage(), exp);
    }
    return retVal != null ? LanguageEnum.getLanguageEnumFromLanguage(retVal) : null;
  }
  
  /**
   * Numerical indication of your request status
   * 
   * @return status_code or 0 if none is available
   */
  public int getStatusCode()
  {
    return getInt(STATUS_CODE, 0);
  }
  
  /**
   * String indication of your request status
   * 
   * @return status_msg or null if none is available
   */
  public String getStatusMessage()
  {
    return getString(STATUS_MESSAGE, null);
  }



  /**
   * Account ID for reference
   * 
   * @return account_id or 0 if none is available
   */
  public int getAccountID()
  {
    return getInt(ACCOUNT_ID, 0);
  }

  /**
   * Account owner's username
   * 
   * @return account_username or null if none is available
   */
  public String getAccountUserName()
  {
    return getString(ACCOUNT_USERNAME, null);
  }

  /**
   * Credit balance
   * 
   * @return credit_balance or 0 if none is available
   */
  public int getCreditBalance()
  {
    return getInt(CREDIT_BALANCE, 0);
  }

  /**
   * byte array with the original content
   * 
   * @return original_content or null if none is available
   */
  public byte[] getOriginalContent()
  {
    return getByteArray(ORIGINAL_CONTENT, null);
  }

  /**
   * byte array with the translated content
   * 
   * @return translated_content or null if none is available
   */
  public byte[] getTranslatedContent()
  {
    return getByteArray(TRANSLATED_CONTENT, null);
  }



  /**
   * Content format
   * 
   * @return ContentTypeEnum or null if none is available
   */
  public ContentTypeEnum getContentType()
  {
    String retVal = null;
    try
    {
      retVal = m_oJSONResponce.getString(CONTENT_TYPE);
    }
    catch (JSONException exp)
    {
      log.debug(exp.getLocalizedMessage(), exp);
    }
    
    return retVal != null ? ContentTypeEnum.valueOf(retVal) : null;
  }

  /**
   * Project ID for reference
   * 
   * @return project_id or 0 if none is available
   */
  public int getProjectID()
  {
    return getInt(PROJECT_ID, -1);
  }

  /**
   * Reported or calculated word count
   * 
   * @return word_count or 0 if none is available
   */
  public int getWordCount()
  {
    return getInt(WORD_COUNT, -1);
  }

  /**
   * Source language
   * 
   * @return source or null if none is available
   */
  public LanguageEnum getSourceLanguage()
  {
    return getLanguage(SOURCE);
  }

  /**
   * Target language
   * 
   * @return account_username or null if none is available
   */
  public LanguageEnum getTargetLanguage()
  {
     return getLanguage(TARGET);
  }

  /**
   * Credits reduced from your balance
   * 
   * @return credits or 0 if none is available
   */
  public int getCredits()
  {
    return getInt(CREDITS, 0);
  }

  /**
   * Unix representation of estimated date and time for translation to be ready
   * GMT Available only when project status is "inProcess" or "disputed" and
   * translation was not submitted (see status codes)
   * 
   * @return estimate_finish or 0 if none is available
   */
  public int getEstimateFinish()
  {
    return getInt(ESTIMATE_FINISH, 0);
  }

  /**
   * translation_ready
   * 
   * @return translation_ready 1 for translation has been submitted, otherwise
   *         0.
   */
  public boolean getTranslationReady()
  {
    int retVal = 0;
    try
    {
      retVal = m_oJSONResponce.getInt(TRANSLATION_READY);
    }
    catch (JSONException exp)
    {
      log.debug(exp.getLocalizedMessage(), exp);
    }
    return retVal == 1 ? true : false;
  }

  /**
   * project_url (string) URL to project page on OneHourTranslation website
   * 
   * @return project_url or null if none is available
   */
  public String getProjectUrl()
  {
    return getString(PROJECT_URL, null);
  }

  /**
   * Errors (string) JSON string
   * 
   * @return Errors or null if none is available
   */
  public String getErrors()
  {
    return getString(ERRORS, null);
  }
  
  /**
   * Client's internal user reference optional (string) JSON string
   * 
   * @return Errors or null if none is available
   */
  public String getUserReference()
  {
    return getString(USER_REFERANCE, null);
  }
  
  /**
   * Client's internal reference to this project (string) JSON string
   * 
   * @return Errors or null if none is available
   */
  public String getProjectReference()
  {
    return getString(PROJECT_REFERANCE, null);
  }
  
  /**
   * Client's internal custom fields from 0 to 9, , 1000 chars maximum (string) JSON string
   * 
   * @return Errors or null if none is available
   */
  public String getCustom(int p_iFieldIndex)
  {
    return getString(CUSTOM + p_iFieldIndex, null);
  }

  
}
